//
//  ViewController.m
//  断点续传
//
//  Created by apple on 15/9/5.
//  Copyright (c) 2015年 戴维营. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()<NSURLConnectionDataDelegate>

{
//  用来存输入的url字符串的；
    NSString *_urlString;
    
    NSInteger _totalLength;//要下载资源的总长度；
    
    NSURLConnection *_con;//connection对象;
    
    NSString *_saveFilePath;//文件路径；

    NSUInteger _loadedLength;//已经下载了的长度；
    
    NSFileHandle *_saveFileHandle;//资源读写的文件句柄；
}
@property (weak, nonatomic) IBOutlet UITextField *urlPathTextField;

@property (weak, nonatomic) IBOutlet UILabel *progressLabel;

@property (weak, nonatomic) IBOutlet UIProgressView *progressView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _saveFilePath = @"/Users/apple/Desktop/123.mp4";
    
    
    // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark - 开始下载
- (IBAction)startDownloadButton:(UIButton *)sender
{
//  开始之前要取消之前的链接；
    [_con cancel];
    
//    构建URL对象和可变的请求对象，因为我们要订制头域来做断点续传；
    
    NSURL *url = [NSURL URLWithString:_urlPathTextField.text];

//    －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
    
//    －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
    
//    拼接断点续传所需的头域信息，从已经传输完以后的字节开始，如果是全新的开始，就是从0字节开始。
    
    NSString *rangeStr = [NSString stringWithFormat:@"bytes=%lu-",_loadedLength];
    
//    设置头域，指定本次请求的资源范围；
 
    
//    －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
   
    [request setValue:rangeStr forHTTPHeaderField:@"Range"];
    
//    －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
    
//    创建链接开始请求资源；
    _con = [NSURLConnection connectionWithRequest:request delegate:self];
    
    [_con start];
    
}

#pragma mark - 停止下载
- (IBAction)stopDownloadButton:(UIButton *)sender
{
    [_con cancel];//终止网络连接；
    
    _con = nil;
    
//    关闭文件
    [_saveFileHandle closeFile];
    _saveFileHandle = nil;
}

//判断是否收到响应；
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//    先类型转换为HTTP对象
    
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    
//    取出HTTP响应中的所有响应头域字典；
    NSDictionary *responseHeaders = httpResponse.allHeaderFields;
    
//    取出本次响应将返回的资源长度，单位为字节；
    
    NSUInteger contentLength = [responseHeaders[@"Content-length"] integerValue];
    
//    计算资源的总长度；
    
    _totalLength =_loadedLength + contentLength;
    
    NSInteger startPos = 0;//准备计算本次响应的起始位置
    
    if (httpResponse.statusCode == 200)
    {
        startPos = 0;//响应码200，代表请求ok，且是非断点续传响应，起始位置为0；
    }
    else if (httpResponse.statusCode == 206)
    {
//        响应码206代表请求ok，且是断点续传的响应，是一部分资源。
        
//        取出本次资源的范围Content-Range的内容是这个格式“bytes 512-1024/4096”,需要解析出起始点512；
        
        NSString *content_range = responseHeaders[@"Content-Range"];
        
        NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:@"- /"];
        
//        用字符分割的方法分割为数组（用－／以及空格字符），起始位置就是第二元素；
        
        NSArray *array = [content_range componentsSeparatedByCharactersInSet:charSet];
        
//        取出第二个元素转为整型变量作为本次资源响应的起始位置；
        startPos = [array[1] integerValue];
        NSLog(@"%@",array);
   
    }
    if (NO ==[[NSFileManager defaultManager] fileExistsAtPath:_saveFilePath ])
    {
        [[NSFileManager defaultManager] createFileAtPath:_saveFilePath contents:nil attributes:nil];
    }
//    上面先判断要保存的文件路径是否存在，不存在则创建；
    
    _saveFileHandle = [NSFileHandle fileHandleForUpdatingAtPath:_saveFilePath];
    [_saveFileHandle truncateFileAtOffset:startPos];//设置文件读写游标到起始位置，
    
//    当前下载进度；
    float percent = (_loadedLength * 1.0)/_totalLength;
    _progressView.progress = percent;
    _progressLabel.text = [NSString stringWithFormat:@"%.1f%%",percent * 100];
}

//接收数据
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [_saveFileHandle writeData:data];//下载下来的数据保存到文件；
    _loadedLength += [data length];//已下载数据长度的计数器累加；
    
//    此方法会根据资源的大小反复的调用很多次，下载的速度取决于资源的大小以及网络带宽的快慢
    
//    计算当前下载进度，并显示到UI
    
    float percent = (_loadedLength * 1.0)/_totalLength;
    _progressView.progress = percent;
    _progressLabel.text = [NSString stringWithFormat:@"%.1f%%",percent * 100];
}

//接收成功；
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//        此方法处理简单
    
//    数据都下载完了也写入文件了
    
//    我们只要关闭文件就ok了，其他的复位；
    
    [_saveFileHandle closeFile];
    _loadedLength = 0;
    _totalLength = 0;
}

//请求失败
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"connection transfer failer");
    [_saveFileHandle closeFile];
    _saveFileHandle = nil;
    _con = nil;
    
//    显示错误时进度；
    float percent = (_loadedLength * 1.0 / _totalLength);
    _progressLabel.text = [NSString stringWithFormat:@"%.1f%% Failed",percent * 100];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
